// #include "napi/native_api.h"
#include "WaterFlowViewComponentInstance.h"
#include "Model/FlowItemViewModel.h"

WaterFlowViewComponentInstance::WaterFlowViewComponentInstance(Context context) : ComponentInstance(std::move(context)) 
{
    
}

void WaterFlowViewComponentInstance::build(){
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "WaterFlowViewComponentInstance", "WaterFlow node build");
    m_stackRootContainerNode.setSize({.width = 300, .height = 500});
    m_stackRootContainerNode.setPosition({.x = 0, .y = 0});
    m_stackRootContainerNode.setBackgroundColor(0xFF00FFFF);
    
//     // iterate view model data; create flowitemView instance.
//     ComponentInstance::Context ctx = {.tag = 1, .componentName = "FlowItemView"};
    
    if(m_waterFlowViewModel == NULL){
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "WaterFlowViewComponentInstance", "Empty View Model");
        return;
    }

    // insert waterflow/refresh 
    // waterflowVM ==> waterflow node;
    m_waterFlowNode.setSize(m_waterFlowViewModel->getSize());
    m_waterFlowNode.setPosition(m_waterFlowViewModel->getStartPosition());
    m_waterFlowNode.setBackgroundColor(SharedColor(m_waterFlowViewModel->getBackgroundColor()));
    m_waterFlowNode.setNodeScrollDelegate(this);
    m_stackRootContainerNode.insertChild(m_waterFlowNode, 0);
    

    
        // 设置ListNode的操作适配器
    m_nodeAdapter = std::make_shared<NodeAdapter>();
    auto counts = m_waterFlowViewModel->getChilds().size();
    m_nodeAdapter->setTotalNodeCount(counts);
    m_nodeAdapter->setDataChangeListener(this);
    m_waterFlowNode.setAdapter(m_nodeAdapter->getNodeAdapterHandle());

    // 设置ListNode的滚动代理
    m_waterFlowNode.setNodeScrollDelegate(this);
    m_waterFlowNode.setCacheCount(2);

    m_nodeAdapter->insertData(0, 1);
    m_nodeAdapter->reloadData(0, 1);


    // TODO: 此处后续改成lazyforeach datasource.
//     std::size_t index = 0;
//     for(auto iter: m_waterFlowViewModel->getChilds()){
//         OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "WaterFlowViewComponentInstance", "flowItem node build");
//         ComponentInstance::Context ctx = {.tag = (int)(index), .componentName = "FlowItemView"};
//         auto flowItemView = std::make_shared<FlowItemViewComponentInstance>(ctx);
//         flowItemView->setModel(iter);
//         m_waterFlowNode.insertChild(flowItemView->getLocalRootArkUINode(), index);
//         index = index + 1;
//     }
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "WaterFlowViewComponentInstance", "flowItem node build finish");
}

void WaterFlowViewComponentInstance::onCreateChild(SharedNodeAdapterEvent sharedNodeAdapterEvent) {
    auto itemIndex = sharedNodeAdapterEvent->getItemIndex();
    ArkUI_NodeHandle waterFlowItem = nullptr;
    auto childs = m_waterFlowViewModel->getChilds();
    auto child = childs[itemIndex];
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "WaterFlowViewComponentInstance", "WaterFlow onCreateChild %{public}d", itemIndex);

    if (!m_nodePool.empty()) {
        // 复用缓存
        // TODO:
        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager", "reusing 0");
        auto node = m_nodePool.top();
        
        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager", "reusing 1");
        m_nodePool.pop();
        
        auto flowItemViewInstance = std::dynamic_pointer_cast<FlowItemViewComponentInstance>(nodeViewMap[node]);

        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager", "reusing 2");
        
        // 更新数据, todo: 封装WaterFlowItem，m_nodePool，避免调用系统接口
        
        // let crash if flowItemViewInstance is NULL; 
        flowItemViewInstance->setModel(child);

        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager", "reusing 3");
        waterFlowItem = flowItemViewInstance->getLocalRootArkUINode().getArkUINodeHandle();

        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager", "reusing 4");
//         nodeViewMap[node] = flowItemViewInstance;
        nodeViewMap[waterFlowItem] = flowItemViewInstance;

        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager", "reusing 5");
    } else {
            OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "WaterFlowViewComponentInstance", "creating");
        ComponentInstance::Context ctx = {.tag = (int)(itemIndex), .componentName = "FlowItemView"};
        auto flowItemViewInstance = std::make_shared<FlowItemViewComponentInstance>(ctx);
        auto iter = m_waterFlowViewModel->getChilds()[itemIndex];
        flowItemViewInstance->setModel(iter);
        waterFlowItem = flowItemViewInstance->getLocalRootArkUINode().getArkUINodeHandle();
        nodeViewMap[waterFlowItem] = flowItemViewInstance;
    }
    sharedNodeAdapterEvent->setItem(waterFlowItem);
}


void WaterFlowViewComponentInstance::onSetChildId(SharedNodeAdapterEvent sharedNodeAdapterEvent) {
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "WaterFlowViewComponentInstance", "WaterFlow onSetChildId");
    int itemIndex = sharedNodeAdapterEvent->getItemIndex();
    auto hash = std::hash<std::string>();
    auto model = m_waterFlowViewModel->getChilds()[itemIndex];
    auto modelInstance = std::dynamic_pointer_cast<FlowItemViewModel>(model);
    auto text = modelInstance->getText();
    sharedNodeAdapterEvent->setNodeId(hash(text));
}

void WaterFlowViewComponentInstance::onRefresh(){

};

void WaterFlowViewComponentInstance::onStateChange(){

};

void WaterFlowViewComponentInstance::onChildInserted(ComponentInstance::Shared const &childComponentInstance,
                                                std::size_t index) {
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "WaterFlowViewComponentInstance", " onChildInserted");
    ComponentInstance::onChildInserted(childComponentInstance, index);
    m_waterFlowNode.insertChild(childComponentInstance->getLocalRootArkUINode(), index);
}

void WaterFlowViewComponentInstance::onChildRemoved(ComponentInstance::Shared const &childComponentInstance) {
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "WaterFlowViewComponentInstance", "WaterFlow onChildRemoved");
    ComponentInstance::onChildRemoved(childComponentInstance);
    m_waterFlowNode.removeChild(childComponentInstance->getLocalRootArkUINode());
}

// ----- WaterFlowNodeScrollDelegate implementation
void WaterFlowViewComponentInstance::onScroll() {
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "WaterFlowViewComponentInstance", "WaterFlow onScroll");
}

void WaterFlowViewComponentInstance::onScrollStart() {
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "WaterFlowViewComponentInstance", "WaterFlow onScrollStart");
}

void WaterFlowViewComponentInstance::onScrollStop() {
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "WaterFlowViewComponentInstance", "WaterFlow onScrollStop");
}

float WaterFlowViewComponentInstance::onScrollFrameBegin(float offset, int32_t scrollState) {
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "WaterFlowViewComponentInstance", "WaterFlow onScrollFrameBegin");
    return offset;
}

// ----- DataChangeWaterFlowener implementation
void WaterFlowViewComponentInstance::onAttachToNode(int32_t index) {
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "WaterFlowViewComponentInstance", "Adapter attach to node %{public}d", index);
}

void WaterFlowViewComponentInstance::onDetachToNode(int32_t index) {
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "WaterFlowViewComponentInstance", "Adapter detach to node %{public}d", index);
}

void WaterFlowViewComponentInstance::onDisposeChild(ArkUI_NodeHandle node) {
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "WaterFlowViewComponentInstance", "OnDisposeChild: %{public}p", node);
    // 缓存节点
    m_nodePool.emplace(node);
}

StackNode &WaterFlowViewComponentInstance::getLocalRootArkUINode() { return m_stackRootContainerNode; }